#include <time.h>
#include "Rect.h"

using namespace game_engine::utils;

///////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
///////////////////////////////////////////////////////////////////////////////

Rect::Rect(void) 
    : origin(), size()
{
}

Rect::Rect(const FLOAT32 coordX, const FLOAT32 coordY, 
    const FLOAT32 h, const FLOAT32 w)
    : origin(coordX, coordY), size(w, h)
{ 
}

Rect::~Rect(void)
{
}

///////////////////////////////////////////////////////////////////////////////
// Other public methods
///////////////////////////////////////////////////////////////////////////////

const Point Rect::getInternalRandomPoint(const Point &offset)
{
    Point res;

    // Calculate random X coordinate
    res.setX(randFloat32(origin.getX(), origin.getX() + size.getWidth()));
    if (res.getX() < offset.getX())
    {
        res.setX(offset.getX());
    }
    else if (res.getX() > (size.getWidth() - offset.getX()))
    {
        res.setX(size.getWidth() - offset.getX());
    }

    // Calculate random Y coordinate
    res.setY(randFloat32(origin.getY(), origin.getY() + size.getHeight()));
    if (res.getY() < offset.getY())
    {
        res.setY(offset.getY());
    }
    else if (res.getY() > (size.getHeight() - offset.getY()))
    {
        res.setY(size.getHeight() - offset.getY());
    }

    return res;
}

const BOOL Rect::isPointWithin(const Point &position) const
{
    BOOL isWithin = false;
    if ((position.getX() >= origin.getX()) && (position.getX() <= (origin.getX() + size.getWidth())))
    {
        if ((position.getY() >= origin.getY()) && (position.getY() <= (origin.getY() + size.getHeight())))
        {
            isWithin = true;
        }
    }
    return isWithin;
}

///////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////

const FLOAT32 Rect::randFloat32(FLOAT32 low, FLOAT32 high)
{
    FLOAT32 temp;

    // verify input parameters
    if (low > high)
    {
        temp = low;
        low = high;
        high = temp;
    }

    // calculate the random number
    temp = (rand() / (RAND_MAX + 1.0f)) * (high - low) + low;

    return temp;
}

///////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////

const FLOAT32 Rect::getX(void) const 
{ 
    return origin.getX(); 
}

const FLOAT32 Rect::getY(void) const 
{ 
    return origin.getY(); 
}

const FLOAT32 Rect::getWidth(void) const 
{ 
    return size.getWidth(); 
}

const FLOAT32 Rect::getHeight(void) const 
{ 
    return size.getHeight(); 
}

///////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////

void Rect::setX(const FLOAT32 coordX) 
{ 
    origin.setX(coordX); 
}

void Rect::setY(const FLOAT32 coordY) 
{ 
    origin.setY(coordY); 
}

void Rect::setWidth(const FLOAT32 w) 
{ 
    size.setWidth(w); 
}

void Rect::setHeight(const FLOAT32 h) 
{ 
    size.setHeight(h); 
}
